<?php

/*
	+------------------------------------------------------------------------------------------------------
	|   调用部分 ：
	|	$upload=new Common_Plugin_UploadFile(); 
	|	print_r($upload->upfile('userfile',array('path'=>'路径','allow_type'=>array(允许上传的类型),'max_size'=>'最大的上传尺寸','overwrite'=>'是否覆盖同名文件','renamed'=>'是否重新命名','error_mode'=>'发生错误的处理方式','filename'=>'文件名称','ifresize'=>'是否产生所略图','resize_width'=>'缩略图的宽','resize_height'=>'缩略图的高','cut'=>'是否截图'))); 
	|	$a = new UploadFile();
	|	$a->upfile("aaa",array('allow_type'=>array('jpg'),'ifresize'=>1,'resize_width'=>$INFO[smallpicset][product][wid],'resize_height'=>$INFO[smallpicset][product][hei],'cut'=>$INFO[smallpicset][product][ifcut]));
	+------------------------------------------------------------------------------------------------------
	*/


class Common_Plugin_UploadFile extends Zend_Controller_Plugin_Abstract{
	
	/**
	 * 上传文件的路径
	 *
	 * @var string
	 */
	var $path;
	
	/**
	 * 相对路径
	 *
	 * @var string
	 */
	var $subpath;
	
	/**
	 * 允许上传的文件类型
	 *
	 * @var string[]
	 */
	var $allow_type=array('jpg','gif','png');
	
	/**
	 * 允许的最大文件大小KB
	 *
	 * @var string
	 */
	var $max_size='5120';
	
	/**
	 * 是否设置成覆盖模式
	 *
	 * @var bool
	 */
	var $overwrite=false;
	
	/**
	 * 是否直接使用上传文件的名称，还是系统自动命名 
	 *
	 * @var bool
	 */
	var $renamed=true;
	
	/**
	 * 是否产生缩略图
	 *
	 * @var bool
	 */
	var $ifresize = false;
	
	/**
	 * 改变后的图片宽度
	 *
	 * @var int
	 */
	var $resize_width;

	/**
	 * 改变后的图片高度
	 *
	 * @var int
	 */
	var $resize_height;
	
	/**
	 * 是否截图
	 *
	 * @var int
	 */
	var $cut;

	
	/**
	 * 上传后文件信息
	 *
	 * @var string[]
	 */
	var $upfile=array();
	
	/**
	 * 上传文件的扩展名
	 *
	 * @var string
	 */
	var $ext='';
	
	/**
	 * 出错信息
	 *
	 * @var string
	 */
	var $errormsg;
	
	/**
	 * 上传后的文件名
	 *
	 * @var string
	 */
	var $filename;
	
	/**
	 * 出错模式
	 *
	 * @var int
	 */
	var $error_mode=0;
	
	/**
	 * 构造函数
	 *
	 * @param string[] $options
	 */
	function __construct($options=array()){
		$this->_set_options($options);
	}
	function UploadFile(){
		$this->_set_options($options);
	}
	/**
	 * 上传文件
	 *
	 * @param var $field
	 * @param string[] $options
	 * @return bool
	 */
	function upfile($field,$options=array())
    {
    	if ($_FILES[$field]['tmp_name']==""){
    		return "";
    	}
    	//设置上传文件的属性 
        $this->_set_options($options);
        //获取文件 
        $this->_set_upfile($field);
        //检查文件 
        $this->_check();
        //设置路径
        $this->path = $this->_set_path();
        //设置上传后的文件名 
        $this->_set_filename();
        //上传文件 
        if(@copy($this->upfile['tmp_name'],$this->upfile['filename'])){
//        	if ($this->ifresize==true && ($this->ext=="gif" || $this->ext=="jpg" || $this->ext=="png" ||$this->ext=="jpeg" )){
//        		include_once ('resizeImage.class.php');
//        		
//        		$obj_small = new resizeImage($this->upfile['filename'],$this->resize_width,$this->resize_height,$this->cut);
//        	}
        	return $this->upfile;
        }
        //上传失败 
        $this->error(__FUNCTION__.'():'.$this->upfile['filename'].'上传失败。');
        return false;
    }
    /**
     * 删除文件
     *
     * @param var $unlink_file
     * @return bool
     */
    function unfile($unlink_file){
    	if("" != $unlink_file){
    		@unlink(BasePath."/".$unlink_file);
    	}
    	return true;
    }
    /**
     * 获取出错信息
     *
     * @return bool
     */
    function get_error()
    {
        if($this->errormsg){
        	return $this->errormsg;
        }
        return false;
    }
    
    /**
     * 设置上传后的文件名
     *
     * @return bool
     */
    function _set_filename()
    {
        //是否重命名 
        if($this->filename){
            //如果用户设置了文件名
            if(file_exists($this->filename)){
            	@unlink($this->filename);
            }
            $this->upfile['filename']=$this->filename;
            return true;
        }

        //检查上传文件路径 
        if(!file_exists($this->path)){
        	$this->_mkpath($this->path);
        }
        if($this->path[strlen($this->path)-1]!='/'){
        	$this->path.='/';
        }
         
        if($this->renamed){
            $ext=$this->ext;
            if(empty($ext))$ext=$this->_get_ext($this->upfile['name']);
            $filename=uniqid(time()).'.'.$ext;
        }else{
            $filename=$this->upfile['name']; 
        }
        //是否覆盖模式 
        if(!$this->overwrite){
            //不覆盖，检查是否存在同名文件 
            $i=1;
            while(file_exists($this->path.$filename)){
                $filename=$i.'_'.$filename;
                $i++;
            }
        }else{
            //覆盖模式，如果存在改文件，则删除
            if(file_exists($this->path.$filename))@unlink($this->path.$filename);
        }
        $this->upfile['filename']=$this->path.$filename;
        $this->upfile['getfilename'] = $this->subpath . "/" . $filename;
    }

	/**
	 * 检查文件是否符合需要
	 *
	 */
    function _check()
    {
        //检查文件大小
        $this->_check_size();
        //检查文件类型
        $this->_check_type();
    }
    
    /**
     * 设置属性
     *
     * @param var $options
     */
    function _set_options($options){
       if(is_array($options)){
           foreach($options as $key=>$value){
               if(in_array($key,array('path','allow_type','max_size','overwrite','renamed','error_mode','filename','ifresize','resize_width','resize_height','cut'))){ 
               		$this->$key = $value;
                   //$this->__set($key,$value);
               }
           }
        }
    }
    
    /**
     * 检查文件类型
     *
     * @return bool
     */
    function _check_type()
    {
        $this->_get_ext($this->upfile['name']);
        if(in_array($this->ext,$this->allow_type)){
            //检查mine类型
            $file_mine=$this->upfile['type'];
            if(empty($file_mine)){
            	return true;
            }
            //检查mine类型是否符合
            $this->_check_mine($file_mine);
        }else{
            $this->error(__FUNCTION__.'():'.$this->upfile['name'].'文件类型'.$this->ext.'不符合。只允许上传'.implode(',',$this->allow_type)); 
        }
    }
    
    /**
     * 检查文件类型
     *
     * @param string $mine
     */
    function _check_mine($mine)
    {
        require('fileType.php');
        $pass=false;
        foreach($this->allow_type as $type){
            if(is_array($filetype[$type])){
                if(in_array($mine,$filetype[$type])){
                    // 
                    $pass=true;
                    break;
                }
            }elseif($filetype[$type]==$mine){
               $pass=true;
               break;
            }elseif(@strstr($_SERVER[HTTP_USER_AGENT],'Firefox') && $this->ext == 'rar'){
               $pass=true;
               break;
	    }
        }
        if(!$pass){
        	$this->error(__FUNCTION__.'():'.$this->upfile['name'].'文件mine类型不符合。只允许上传'.implode(',',$this->allow_type)); 
        }
    }
    
    /**
     * 获取文件的后缀 
     *
     * @param string $file
     * @return string
     */
    function _get_ext($file){
        $ext = explode(".", $file);
        $ext = $ext[count($ext) - 1];
        $this->ext=strtolower($ext);
        return $this->ext;
    }
    
    /**
     * 检查文件大小
     *
     */
    function _check_size()
    { 
        if($this->upfile['size']>$this->max_size*1024){
        	$this->error(__FUNCTION__.'()：'.$this->upfile['name'].'文件大小超过了限制'.$this->max_size.'MB');  	
        }
    }
    
    /**
     * 获取文件
     *
     * @param object $field
     */
	function _set_upfile($field)
    {
        if(!$_FILES[$field]){
        	$this->error(__FUNCTION__.'()：文件不存在！');
        }
        $this->upfile=$_FILES[$field];
    }

    /**
     * 设置属性值
     *
     * @param string $key
     * @param var $value
     */
	function __set($key,$value){
        $this->$key=$value;
    }

    /**
     * 创建目录
     *
     * @param string $path
     * @param string $mode
     * @return bool
     */
	function _mkpath($path,$mode=0775){
		
		$path=str_replace("\\","/",$path);
		$path_info=explode('/',$path);
		$total=count($path_info);
		$path='';
		$line = "/";
		
        for($i=0;$i<$total;$i++)
        {
            $path.=$path_info[$i].$line;
            if(empty($path_info[$i])){
            	continue;
            }
            if(file_exists($path))
            {
                continue;
            }else{
                if(!@mkdir($path,$mode)){
                	$this->error(__FUNCTION__.'(),创建'.$path.'出错！因为我们为了分布式文件存储适应大规模商业应用，但是您的服务器或虚拟主机并不提供此类支持。');
                }
            }
        }
        return true;
    }

    /**
     * 格式化文件大小
     *
     * @param int $size
     * @return string
     */
    function format_size($size) 
    { 
        if($size<1024){ 
            return $size.'B'; 
        }elseif ($size<1024*1024){ 
            return number_format((double)($size/1024),2).'KB'; 
        }else{ 
            return number_format((double)($size/(1024*1024)),2).'MB'; 
        } 
    } 
    
    /**
     * 出错处理
     *
     * @param string $msg
     */
    function error($msg) 
    {
        if($this->error_mode==0){
        	die('ERROR : file '.__FILE__.' function '.$msg);
        }
        $this->errormsg.= $msg;
    }
    
    /**
     * 设置路径
     *
     * @return string
     */
    function _set_path(){
    	$config=new Zend_Config_Ini('./application/config/config.ini',null, true);//加载配置文件
    	if ($this->path==""){
    		switch($config->file->file->savetype){
    			case "1":
    				//按文件类型存放，htm/a.jpg
    				$this->subpath = $config->file->file->path . $this->ext;
    				break;
    			case "2":
    				//按文件类型存放，再细化到年，htm/2007/a.jpg
    				$this->subpath = $config->file->file->path . $this->ext . "/" . date("Y",time());
    				break;
    			case "3":
    				//按文件类型存放，再细化到月，htm/2007/07/a.jpg
    				$this->subpath = $config->file->file->path . $this->ext . "/" . date("Y",time()) . "/" . date("m",time());
    				break;
    			case "4":
    				//按文件类型存放，再细化到日，htm/2007/07/12/a.jpg
    				$this->subpath = $config->file->file->path . $this->ext . "/" . date("Y",time()) . "/" . date("m",time()) . "/" . date("d",time());
    		}
    		
    		return  $this->subpath;
    	}
    	else{
    		return $this->path;
    	}
    }

}
?>